﻿//========================================================================//
//      Copyright 2012, Smilodon Studio Inc.
//      All rights reserved.
//========================================================================//

/**
 *	particle system
 *      @author: CYS
 */




var particle = function(x, y, vx, vy, ax, ay, d, r, f, target, c)
{
	this.x      = x || 0;
	this.y      = y || 0;
	this.vx     = vx || 0;
	this.vy     = vy || 0;
	this.ax     = ax || 0;
	this.ay     = ay || 0;
	this.d      = d || 0;
	this.r      = r || 0;		// radius
	this.f      = f || 0;		// friction
	this.target = target || 0;	// target point
	this.c = c;
}


particle.prototype.draw = function() 
{
	g2D.fillStyle = this.c;
	g2D.beginPath();
	g2D.arc(this.x, this.y, this.r, 0, 2*Math.PI, true);
	g2D.closePath();
	g2D.fill();
}



var trails = function()
{
	this.ts = [];

}



trails.prototype.numPoints = 32;
trails.prototype.init = function(w, h, numTrails)
{
	for(var i = 0; i < numTrails; i++)
	{
		var x = rnd(w);
		var y = rnd(h);
		var c = rndColorHSL();

		var ts = [];
		var N = this.numPoints;

		for (var j = 0; j < N; j++) 
		{
			ts[j] = new particle(x, y, 0, 0, rnd(10.8)+0.5, rnd(10.8)+0.5, i%2*2-1, 2.5*(1-j/N)*h/1024+0.5, rnd(0.2)+0.7, ~~rnd(numTrails), c);	
		}

		this.ts[i] = ts;

	}
}



trails.prototype.updata = function(targetShape)
{
	var N = this.ts.length;
	for (var i = 0; i < N; i++) 
	{
		var t = this.ts[i];
		var p0 = t[0];
		var tp = targetShape[p0.target];
		var dx = p0.x - tp[0];
		var dy = p0.y - tp[1];
		var ds = Math.sqrt(dx*dx + dy*dy);

		if(ds < 10)
		{
			if(rnd() > 0.95) p0.target = ~~(rnd(N));
			else
			{
				if(rnd() > 0.99) p0.d *= -1;
				p0.target += p0.d;
				if(p0.target < 0) p0.target += N;
				if(p0.target >= N) p0.target -= N;
			}
		}

		var ddx = -dx/ds;
		var ddy = -dy/ds;
		p0.vx += ddx*p0.ax - ddy*(rnd(2.0) - 1);
		p0.vy += ddy*p0.ay + ddx*(rnd(2.0) - 1);
		p0.x += p0.vx;
		p0.y += p0.vy;
		p0.draw();
		p0.vx *= p0.f;
		p0.vy *= p0.f;
		p0.ax = rnd(0.4)+0.5;
		p0.ay = rnd(0.4)+0.5;

		for(var j = 0; j < this.numPoints-1; j++)
		{
			var curP = t[j];
			var nxtP = t[j+1];
			nxtP.x += (curP.x - nxtP.x)*0.8;
			nxtP.y += (curP.y - nxtP.y)*0.8;

			nxtP.draw();
		}

	}
}



function heartShape(mx, my)
{
	for(var i = 0; i < numHeartPoints;  i++)
	{
		var C = Math.cos;
		var s = Math.PI*2*i/numHeartPoints;
		var x = mx + height*0.32*Math.pow(Math.sin(s), 3);
		var y = my + height*0.32/18.0 * (-(15*C(s) - 5*C(2*s) - 2*C(3*s) - C(4*s)));
		heartPoints[i] = [x, y];
	}
}



//----------------------------------------------------------------------------
// star
//
var stars = function(n)
{
	this.s = [];
	this.num = n;
	this.mx = 0;
	this.my = 0;
	this.depth = 3000;
	this.nearPlane = 10;
	this.size = 60;
	this.speed = 5;
}


stars.prototype.resetStar = function(s)
{
	s.x = (rnd() - 0.5)*width;
	s.y = (rnd() - 0.5)*height;
	s.z = this.depth;
}


stars.prototype.init = function() 
{
	for(var i=0; i<this.num; i++)
	{
		var s = {};
		this.resetStar(s);
		s.z = this.depth - rnd(0.618)*this.depth;
		this.s.push(s);
	}
};


stars.prototype.draw = function(mousex, mousey)
{
	var kk = 0.5;
	this.mx = mousex*(1-kk) + this.mx*kk;
	this.my = mousey*(1-kk) + this.my*kk;
	
	// stars
	for(var i = 0; i < this.num; i++)
	{
		var star = this.s[i];
		
		var z = star.z - this.speed;
		var x = star.x * star.z/z;
		var y = star.y * star.z/z;
		starWidth = 3/star.z + 0.3;
		
		var r = sin(Q*i + r) * 64 + W;
		var g = sin(Q*i+2+r) * 64 + W;
		var b = sin(Q*i+4+r) * 64 + W;
		
		if(star.x != 0)
		{
			g2D.strokeStyle = "rgb(" + ~~r + "," + ~~g + "," + ~~b+ ")";
			g2D.lineWidth = starWidth;
			g2D.beginPath();
			g2D.moveTo(x + this.mx,  y + this.my);
			g2D.lineTo(star.x + this.mx + 0.9,  star.y + this.my + 0.9);
			g2D.stroke();

		}
		
		star.x = x;
		star.y = y;
		star.z = z;
		if(star.x > width || star.y > height || star.z < this.nearPlane) resetStar(star);
	}
	
	r += 0.1;
}
